/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#ifndef __NOISE_HARD_ANDROID_CHANNEL_H__
#define __NOISE_HARD_ANDROID_CHANNEL_H__

#include <noise/Manager.h>
#include <noise/hard/Channel.h>
#include <math/Vector3.h>
#include <SharedRep.h>
#include <Atom.h>
#include <list>
#include <deque>

namespace liba
{
namespace noise
{
namespace hard
{
namespace android
{
class Hardware;

class ChannelStaticRepName
{
public:
	Atom channel_type;
	filesystem::String name;
	Hardware * hardware;

	ChannelStaticRepName(Hardware * hardware, const Atom & channel_type, const filesystem::String & name):
		hardware( hardware ),
		channel_type( channel_type ),
		name( name )
	{}
	bool operator<(const ChannelStaticRepName & na)const
	{
		if( hardware < na.hardware )
			return true;
		if( hardware > na.hardware )
			return false;
		if( channel_type < na.channel_type )
			return true;
		if( channel_type > na.channel_type )
			return false;
		return name < na.name;
	}
};

class ChannelStaticRep
{
public:
	int soundId;
	int frequency;
	int size;
public:
	int get_frequency()const
	{
		return frequency;
	}
	int get_size()const
	{
		return size;
	}

	ChannelStaticRep(const ChannelStaticRepName & name);
	~ChannelStaticRep();
};

class Channel : public hard::Channel
{
protected:
	bool loop;
	double exact_volume;
	double min_distance, max_distance;
	double exact_pan;
	math::Vector3<float> exact_position;
	math::Vector3<float> exact_speed;
	
	virtual bool change_attribute(const Atom & name, const math::Vector3<float> & value);
	virtual bool change_attribute(const Atom & name, double value);
	virtual bool get_attribute(const Atom & name, math::Vector3<float> * value)const;
	virtual bool get_attribute(const Atom & name, double * value)const;
public:
	Channel();
	~Channel();
};

class ChannelStatic :
	public Shared<ChannelStaticRepName, ChannelStaticRep>,
	public Channel
{
	Atom channel_type;
	unsigned position;
	double approx_vol;
	bool finished;
	bool in_existance_flag;
	
public:
	int playingSoundId;

	static bool SortPredicate(ChannelStatic * a, ChannelStatic * b)
	{
		return a->approx_vol > b->approx_vol;
	}
	ChannelStatic(Hardware * ha, const Atom & channel_type, const filesystem::String & name);
	virtual ~ChannelStatic();
	void life_cycle(double delta_time, const math::Vector3<float> & listener_position);
	bool in_existance()const
	{
		return in_existance_flag;
	}
	void come_to_existance();
	void begone();
	virtual void play(DataSource * source);
	virtual void stop();
	virtual bool is_finished();
	void on_hardware_delete();
};


} // namespace android
} // namespace hard
} // namespace noise
} // namesapce liba
using namespace liba;

#endif // __NOISE_HARD_ANDROID_CHANNEL_H__

